package net.tv90.bfmccore.game;

import lk.vexview.api.VexViewAPI;
import lk.vexview.builders.GuiBuilder;
import lk.vexview.gui.VexGui;
import lombok.Data;
import net.tv90.bfmccore.BFMCCore;
import net.tv90.bfmccore.constant.GameConstant;
import net.tv90.bfmccore.event.GameLoseEvent;
import net.tv90.bfmccore.event.GameSameEvent;
import net.tv90.bfmccore.event.GameWinEvent;
import net.tv90.bfmccore.event.ServerExceptionEvent;
import net.tv90.bfmccore.game.ai.AISystem;
import net.tv90.bfmccore.game.commander.ICommanderSystem;
import net.tv90.bfmccore.game.impl.cq.ConquestArea;
import net.tv90.bfmccore.game.view.GameModelViewHandler;
import net.tv90.bfmccore.game.view.MapCoordConverter;
import net.tv90.bfmccore.helper.FactionHelper;
import net.tv90.bfmccore.helper.FlanHelper;
import net.tv90.bfmccore.helper.MCHHelper;
import net.tv90.bfmccore.squad.Squad;
import net.tv90.bfmccore.util.Cooldown;
import net.tv90.bfmccore.util.GeneralUtil;
import net.tv90.bfmccore.util.file.FileUtils;
import net.tv90.bfmccore.util.vector.Vector3f;
import net.tv90.bfmccore.util.vector.Vector3i;
import org.bitterorange.flansmodslain.FlansModAPI;
import org.bitterorange.flansmodslain.models.EntitySoldierWrapper;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;

import java.io.File;
import java.util.*;

import static net.tv90.bfmccore.BFMCCore.plugin;
import static net.tv90.bfmccore.game.GameManager.waitingPlayers;
import static net.tv90.bfmccore.game.impl.GunMasterGame.playerSlotProgress;
import static net.tv90.bfmccore.helper.FactionHelper.*;
import static net.tv90.bfmccore.listener.AntiCheatListener.clearInventory;
import static net.tv90.bfmccore.listener.AntiCheatListener.setHideName;
import static net.tv90.bfmccore.squad.Squad.clearSquadMap;
import static org.bukkit.GameMode.ADVENTURE;

@Data
public abstract class GameBase implements IGame {

    //游戏内玩家列表
    public static Set<Player> inGamePlayerList = new HashSet<>();
    //阵营A玩家列表
    public static Set<Player> firstFactionList = new HashSet<>();
    //阵营B玩家列表
    public static Set<Player> secondFactionList = new HashSet<>();
    //阵营允许加入的最大玩家数量
    public static int factionMaxSize;
    //循环帧
    public static int frame;
    //指挥官系统
    public ICommanderSystem commanderSystem = null;
    //AI系统
    public AISystem aiSystem = null;
    //每方最大AI数量
    public int maxAi = 4;
    //当前载具数量
    public Map<String, Integer> vehicleInfo = new HashMap<>();
    //当前阵营A的AI数量
    public int firstFactionCurrentAiNum = 0;
    //当前阵营B的AI数量
    public int secondFactionCurrentAiNum = 0;
    //AI刷新时间,单位:秒
    public int timeToSpawnAi = 10;
    //地图名称，请填写MV多世界名字
    public String mapName;
    //地图名称的中文翻译
    public String mapName_Lang = "";
    //游戏模式的中文翻译(仅用于显示)
    public String gameMode;
    //游戏模式
    public EnumGameType gameType;
    //阵营A名称(RU,US,CN)
    public String firstFactionName;
    //阵营B名称(RU,US,CN)
    public String secondFactionName;
    //世界主出生点
    public Vector3i mainSpawnPoint;
    //阵营A主出生点
    public Vector3i firstFactionMainSpawnPoint;
    //阵营B主出生点
    public Vector3i secondFactionMainSpawnPoint;
    //战局最大时间(秒)
    public int maxTime;
    //战局当前时间(秒)
    public int currentTime;
    //战局最大兵力值
    public int maxTicket;
    //阵营A当前兵力值
    public int firstFactionTicket;
    //阵营B当前兵力值
    public int secondFactionTicket;
    //是否由管理员强制结束游戏
    public boolean executeEnd = false;
    //是否结束游戏
    public boolean isEnd;
    public MapCoordConverter mapCoordConverter;

    public int maxLightVehicleNum = 2;
    public int maxTankNum = 2;
    public int maxAANum = 1;
    public int maxHeliNum = 1;
    public int maxTransHeliNum = 1;
    public int maxJetNum = 1;
    public int maxAtkJetNum = 1;
    public int maxFacNum = 1;

    public int lightVehicleCooldownTime = 60;
    public int tankCooldownTime = 80;
    public int aaCooldownTime = 180;
    public int heliCooldownTime = 220;
    public int transHeliCooldownTime = 120;
    public int jetCooldownTime = 160;
    public int atkJetCooldownTime = 220;
    public int facCooldownTime = 120;

    /**
     * 初始化游戏资源
     *
     * @param mapName                     地图名称
     * @param gameMode                    游戏模式
     * @param firstFactionName            阵营1名称
     * @param secondFactionName           阵营2名称
     * @param mainSpawnPoint              世界重生点
     * @param firstFactionMainSpawnPoint  阵营1重生点
     * @param secondFactionMainSpawnPoint 阵营2重生点
     */
    public void initGameSource(String mapName, String gameMode, String firstFactionName, String secondFactionName, Vector3i mainSpawnPoint, Vector3i firstFactionMainSpawnPoint, Vector3i secondFactionMainSpawnPoint, List<ConquestArea> pointList) {
        this.mapName = mapName;
        this.gameMode = gameMode;
        this.firstFactionName = firstFactionName;
        this.secondFactionName = secondFactionName;
        this.mainSpawnPoint = mainSpawnPoint;
        this.firstFactionMainSpawnPoint = firstFactionMainSpawnPoint;
        this.secondFactionMainSpawnPoint = secondFactionMainSpawnPoint;
    }

    public void initGameSource(String mapName, String gameMode, String firstFactionName, String secondFactionName, Vector3i mainSpawnPoint, Vector3i firstFactionMainSpawnPoint, Vector3i secondFactionMainSpawnPoint, List<Vector3i> firstFactionSpawnPointList, List<Vector3i> secondFactionSpawnPointList){
        this.mapName = mapName;
        this.gameMode = gameMode;
        this.firstFactionName = firstFactionName;
        this.secondFactionName = secondFactionName;
        this.mainSpawnPoint = mainSpawnPoint;
        this.firstFactionMainSpawnPoint = firstFactionMainSpawnPoint;
        this.secondFactionMainSpawnPoint = secondFactionMainSpawnPoint;
    }

    public void setMapName_Lang(String mapName_Lang) {
        this.mapName_Lang = mapName_Lang;
    }

    public void setGameType(EnumGameType type) {
        this.gameType = type;
    }

    /**
     * 设置该局游戏票数
     *
     * @param max 票数
     */
    public void setTicket(int max) {
        this.maxTicket = max;
        this.firstFactionTicket = max;
        this.secondFactionTicket = max;
    }

    /**
     * 设置该局游戏时间
     *
     * @param time 时间(单位:秒)
     */
    public void setTime(int time) {
        this.maxTime = time;
        this.currentTime = time;
    }

    /**
     * 玩家加入游戏
     *
     * @param p 玩家
     */
    public void joinGame(Player p) {
        if (waitingPlayers.contains(p) || inGamePlayerList.contains(p)) {
            p.sendMessage("§e[管理员]不能重复加入游戏");
            return;
        }
        if (GameManager.getInstance().currentGame.isEnd()) {
            return;
        }
        waitingPlayers.add(p);
        inGamePlayerList.add(p);
        p.sendMessage("§e[管理员]你已进入游戏对局，做好战斗准备");
        //p.setBedSpawnLocation(mainSpawnPoint.toLocation(Bukkit.getWorld(this.mapName)));
        clearInventory(p);
        GameUtils.setSpawnPoint(p, mainSpawnPoint);
        setHideName(p, true);
        p.setHealth(20);
        p.setFoodLevel(20);
        p.setGameMode(ADVENTURE);
        p.setNoDamageTicks(200);
        p.closeInventory();
        teleportSinglePlayer(p, this.mapName);
        GameModelViewHandler.getInstance().createSelectFactionGUI(p, firstFactionName, secondFactionName);
        if (gameType.equals(EnumGameType.GUNMASTER)) playerSlotProgress.put(p, 0);
    }

    /**
     * 该局游戏启动
     *
     * @param game 游戏
     */
    public void onStart(GameBase game) {
        frame = 0;
        setTicket(game.maxTicket);
        setTime(game.maxTime);
        System.out.println("该局游戏启动");
        firstFactionList.clear();
        secondFactionList.clear();
        inGamePlayerList.clear();
        firstFactionCurrentAiNum = 0;
        secondFactionCurrentAiNum = 0;
        new GameThread().runTaskTimer(plugin, 20L, 20L);
        executeEnd = false;
        isEnd = false;
        updateSize();
        applyVehicleLimit();
        applyVehicleCooldown();
        initVehicleCount();
        onCustomStart();
    }

    /**
     * 该局游戏结束
     *
     * @param reason 结束原因
     */
    public void onEnd(String reason) {
        frame = 0;
        System.out.println("该局游戏结束," + reason);
        isEnd = true;
        firstFactionList.clear();
        secondFactionList.clear();
        inGamePlayerList.clear();
        firstFactionCurrentAiNum = 0;
        secondFactionCurrentAiNum = 0;
        Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "killall all " + this.mapName);
        clearSquadMap();
        Bukkit.getOnlinePlayers().forEach(p -> {
            setHideName(p, false);
            clearInventory(p);
            p.setHealth(20);
            p.setFoodLevel(20);
            p.setNoDamageTicks(200);
            p.closeInventory();
            MCHHelper.setINF(p);
            Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "spawnpoint " + p.getName() + " 67 67 52");
            Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "scoreboard teams leave " + p.getName());
            p.sendMessage("§e[管理员]对局结果:" + reason);
            p.sendMessage("§e[管理员]下一局游戏将在 " + GameConstant.MAX_WAITING_TICK / GameConstant.TICK_RATE + "s 后开启");
        });
        MCHHelper.flushVehicleLimit();
        onCustomEnd();
        Bukkit.getScheduler().runTask(plugin, this::replaceMap);
    }

    /**
     * 将玩家传送至坐标
     *
     * @param p   玩家
     * @param vec 三维坐标
     */
    @Deprecated
    public void teleportSinglePlayer(Player p, Vector3i vec) {
        p.teleport(vec.toLocation(Bukkit.getWorld(this.mapName)));
    }

    /**
     * 将玩家传送至坐标
     *
     * @param p   玩家
     * @param vec 三维坐标
     */
    public void teleportSinglePlayer2(Player p, Vector3i vec) {
        Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tp " + p.getName() + " " + vec.x + " " + vec.y + " " + vec.z);
    }

    /**
     * 将玩家传送至坐标
     *
     * @param p   玩家
     * @param vec 三维坐标
     */
    public void teleportSinglePlayer(Player p, Vector3f vec) {
        p.teleport(vec.toLocation(Bukkit.getWorld(this.mapName)));
    }

    /**
     * 将玩家传送至世界重生点
     *
     * @param p     玩家
     * @param world 世界名称
     */
    public void teleportSinglePlayer(Player p, String world) {
        p.teleport(Bukkit.getWorld(world).getSpawnLocation());
    }

    /**
     * 将玩家传送至战场
     *
     * @param p 玩家
     */
    public abstract void teleportSinglePlayerToBattleField(Player p);

    /**
     * 更新每个阵营最多能容纳的玩家数量 为总玩家数量 / 2 + 2
     */
    public void updateSize() {
        factionMaxSize = Bukkit.getOnlinePlayers().size() / 2 + 2;
    }

    /**
     * 随机给玩家分配阵营
     */
    public void randomAllocateFaction() {
        for (int i = 0; i <= Bukkit.getOnlinePlayers().size(); i++) {
            if (i % 2 == 0) joinFirstFaction((Player) Bukkit.getOnlinePlayers().toArray()[i]);
            else joinSecondFaction((Player) Bukkit.getOnlinePlayers().toArray()[i]);
        }
    }

    public void createSelectFactionGUI(Player p, String firstFactionName, String secondFactionName) {
        int windowWidth = VexViewAPI.getPlayerClientWindowWidth(p);
        int windowHeight = VexViewAPI.getPlayerClientWindowHeight(p);
        VexGui gui = GuiBuilder.builder()
                .image(img -> img.location(110 * windowWidth / 854, -1).background("[local]BattleField/" + firstFactionName + ".png").size(200 * windowWidth / 854, 200 * windowHeight / 445))
                .image(img -> img.location(550 * windowWidth / 854, -1).background("[local]BattleField/" + secondFactionName + ".png").size(200 * windowWidth / 854, 200 * windowHeight / 445))
                .button(btn -> btn
                        .id("FirstFactionSelectButton")
                        .background("[local]GUI/button.png", "[local]GUI/button_focus.png")
                        .unClickable("[local]GUI/button_focus.png")
                        .size(100 * windowWidth / 854, 30 * windowHeight / 445)
                        .location(160 * windowWidth / 854, 350 * windowHeight / 445)
                        .text("加入" + getCountry_Lang2(firstFactionName))
                        .clickable(true)
                        .click(this::joinFirstFaction))
                .button(btn -> btn
                        .id("SecondFactionSelectButton")
                        .background("[local]GUI/button.png", "[local]GUI/button_focus.png")
                        .unClickable("[local]GUI/button_focus.png")
                        .size(100 * windowWidth / 854, 30 * windowHeight / 445)
                        .location(600 * windowWidth / 854, 350 * windowHeight / 445)
                        .text("加入" + getCountry_Lang2(secondFactionName))
                        .clickable(true)
                        .click(this::joinSecondFaction))
                .closable(false)
                .size(windowWidth, windowHeight)
                .build("[local]GUI/main.png", -1, -1);
        VexViewAPI.openGui(p, gui);
    }

    public void changeFaction(Player p) {
        GameModelViewHandler.getInstance().createSelectFactionGUI(p, firstFactionName, secondFactionName);
    }

    public synchronized final void joinFirstFaction(Player p) {
        secondFactionList.remove(p);
        firstFactionList.add(p);
        GameUtils.setSpawnPoint(p, firstFactionMainSpawnPoint);
        p.sendMessage("§e[管理员]已选择" + firstFactionName + "阵营");
        p.teleport(firstFactionMainSpawnPoint.toLocation(Bukkit.getWorld(this.mapName)));
        switch (firstFactionName) {
            case "RU": {
                selectFaction(p, "RU");
                break;
            }
            case "US": {
                selectFaction(p, "US");
                break;
            }
            case "CN": {
                selectFaction(p, "CN");
                break;
            }
        }
        Squad.autoJoin(p);
    }

    public synchronized final void joinSecondFaction(Player p) {
        firstFactionList.remove(p);
        secondFactionList.add(p);
        GameUtils.setSpawnPoint(p, secondFactionMainSpawnPoint);
        p.sendMessage("§e[管理员]已选择" + secondFactionName + "阵营");
        p.teleport(secondFactionMainSpawnPoint.toLocation(Bukkit.getWorld(this.mapName)));
        switch (secondFactionName) {
            case "RU": {
                selectFaction(p, "RU");
                break;
            }
            case "US": {
                selectFaction(p, "US");
                break;
            }
            case "CN": {
                selectFaction(p, "CN");
                break;
            }
        }
        Squad.autoJoin(p);
    }

    /**
     * 玩家选择阵营
     *
     * @param p       玩家
     * @param faction 阵营
     */
    private synchronized void selectFaction(Player p, String faction) {
        p.closeInventory();
//        if(firstFactionList.size() >= factionMaxSize || secondFactionList.size() >= factionMaxSize){
//            p.sendMessage("§e[管理员]该阵营人数已满！["+ firstFactionList.size() + "/" + factionMaxSize +"]");
//            return;
//        }
        clearInventory(p);
        setCountry(p, faction);
        setHideName(p, true);
        setFaction(p, "ASS");
        waitingPlayers.remove(p);
        GameModelViewHandler.getInstance().createMainGUI(p);
    }

    /**
     * 将一名玩家传送至所属阵营出生点，若无阵营，传送到世界出生点
     *
     * @param p 玩家
     */
    public void teleportSinglePlayerToSpawnPoint(Player p) {
        String country = getCountry2(p);
        if (country.equals(firstFactionName)) {
            teleportSinglePlayer2(p, firstFactionMainSpawnPoint);
        } else if (country.equals(secondFactionName)) {
            teleportSinglePlayer2(p, secondFactionMainSpawnPoint);
        } else teleportSinglePlayer2(p, mainSpawnPoint);
    }

    /**
     * 给某玩家所在的阵营扣除指定票数
     *
     * @param player 玩家
     * @param num    票数
     */
    public final void subTicket(Player player, int num) {
        if (isEnd) return;
        if (getCountry2(player).equals(firstFactionName)) {
            firstFactionTicket -= num;
        } else if (getCountry2(player).equals(secondFactionName)) {
            secondFactionTicket -= num;
        }
    }

    public final void addTicket(Player player, int num) {
        if (isEnd) return;
        if (getCountry2(player).equals(firstFactionName)) {
            firstFactionTicket += num;
        } else if (getCountry2(player).equals(secondFactionName)) {
            secondFactionTicket += num;
        }
    }

    public final void subTicket(EntitySoldierWrapper player, int num) {
        if (isEnd) return;
        if (getCountry2(player).equals(firstFactionName)) {
            firstFactionTicket -= num;
        } else if (getCountry2(player).equals(secondFactionName)) {
            secondFactionTicket -= num;
        }
    }

    /**
     * 给某玩家的敌方阵营扣除指定票数
     *
     * @param player 玩家
     * @param num    票数
     */
    public final void subEnemyTicket(Player player, int num) {
        if (isEnd) return;
        if (getCountry2(player).equals(firstFactionName)) {
            secondFactionTicket -= num;
        } else if (getCountry2(player).equals(secondFactionName)) {
            firstFactionTicket -= num;
        }
    }

    public final void subEnemyTicket(EntitySoldierWrapper player, int num) {
        if (isEnd) return;
        if (getCountry2(player).equals(firstFactionName)) {
            secondFactionTicket -= num;
        } else if (getCountry2(player).equals(secondFactionName)) {
            firstFactionTicket -= num;
        }
    }

    public final void subTicket(String faction, int num) {
        if (isEnd) return;
        if (faction.equals(firstFactionName)) {
            firstFactionTicket -= num;
        } else if (faction.equals(secondFactionName)) {
            secondFactionTicket -= num;
        }
    }

    public final void subEnemyTicket(String faction, int num) {
        if (isEnd) return;
        if (faction.equals(firstFactionName)) {
            secondFactionTicket -= num;
        } else if (faction.equals(secondFactionName)) {
            firstFactionTicket -= num;
        }
    }

    /**
     * 获胜队伍结算界面
     */
    public abstract void showWinHUD(Set<Player> list);

    /**
     * 失败队伍结算界面
     */
    public abstract void showLoseHUD(Set<Player> list);

    /**
     * 平局结算界面
     */
    public abstract void showSameHUD(Set<Player> list);

    /**
     * 游戏强制结束结算界面
     */
    public abstract void showExecuteHUD(Set<Player> list);

    /**
     * 在玩家屏幕显示游戏信息
     */
    public abstract void showGameInfo();

    /**
     * 获取游戏信息
     */
    public abstract String getGameInfo();

    public boolean isEnd() {
        return isEnd;
    }

    /**
     * 游戏循环
     *
     * @param tps
     */
    public void tick(int tps) {
    }

    public final synchronized void addVehicle(Player adder, String vehicleType) {
        if (firstFactionList.contains(adder)) {
            String key = "1_" + vehicleType;
            if (vehicleInfo.containsKey(key)) {
                vehicleInfo.put(key, vehicleInfo.get(key) + 1);
            } else {
                vehicleInfo.put(key, 1);
            }
        } else if (secondFactionList.contains(adder)) {
            String key = "2_" + vehicleType;
            if (vehicleInfo.containsKey(key)) {
                vehicleInfo.put(key, vehicleInfo.get(key) + 1);
            } else {
                vehicleInfo.put(key, 1);
            }
        }
    }

    /**
     * 重置地图
     */
    public final void replaceMap() {
        try {
            Thread.sleep(1000L);
            System.out.println("正在卸载地图" + this.mapName);
            Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "mv unload " + this.mapName); //TODO 报错
            Thread.sleep(1000L);
            System.out.println("正在替换区块");
            File source = new File(BFMCCore.PLUGIN_ROOT, "map/region/" + this.mapName);
            File target = new File("./world/" + this.mapName);
            FileUtils.copyDir(source, target);
            Thread.sleep(1000L);
            System.out.println("正在加载地图" + this.mapName);
            Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "mv load " + this.mapName);
            System.out.println("地图" + this.mapName + "重置成功");
        } catch (Exception e) {
            Bukkit.getServer().getPluginManager().callEvent(new ServerExceptionEvent(e));
            e.printStackTrace();
        }
    }

    /**
     * 指挥官系统每秒执行一次
     */
    public final void commandSystemTick() {
        commanderSystem.tick(this);
    }

    public boolean isAboutToEnd() {
        return currentTime <= 60 || firstFactionTicket <= 10 || secondFactionTicket <= 10;
    }

    public void generateMenu(){};

    public abstract void deploy(Player p);

    public void deployOnRandomAircraftEntity(Player p, String type) {
        List<Player> list = new ArrayList<>();
        for (Player player : FactionHelper.getTeammates(p)) {
            if(FactionHelper.isInSameWorld(p, player)) {
                if (player.getVehicle() != null && FlansModAPI.isMCHeliAircraft(player.getVehicle())) {
                    if (FlanHelper.getWeaponType(FlansModAPI.getPlayerVehicle(player)).equals(type)) {
                        list.add(player);
                    }
                }
            }
        }
        if(list.isEmpty()) {
            GameModelViewHandler.getInstance().createInfoGui(p, "当前无" + FlanHelper.WeaponTypeMap.get(type) + "可供部署",
                    GameModelViewHandler.getInstance()::createMainGUI);
        } else {
            Player randPlayer = GeneralUtil.getRandomElement(list);
            if(randPlayer != null && randPlayer.getVehicle() != null && FlansModAPI.mountFirstEmptySeat(p, randPlayer.getVehicle())) {
                if (Cooldown.isCool("Deploy", p)) {
                    p.sendMessage("§a[队伍]部署冷却时间剩余" + Cooldown.getTime("Deploy", p) + "秒");
                }
                p.playSound(p.getLocation(), "custom.Deploy", 20.0F, 1.0F);
                deploy(p);
                randPlayer.sendMessage("§a[队伍]玩家" + p.getName() + "已传送至你的载具上");
            } else {
                GameModelViewHandler.getInstance().createInfoGui(p, "部署到" + FlanHelper.WeaponTypeMap.get(type) + "失败",
                        GameModelViewHandler.getInstance()::createMainGUI);
            }
        }
    }

    protected void applyVehicleLimit() {
        MCHHelper.vehicleLimit.clear();
        MCHHelper.vehicleLimit.put("LIGHT", maxLightVehicleNum);
        MCHHelper.vehicleLimit.put("ATKJET", maxAtkJetNum);
        MCHHelper.vehicleLimit.put("JET", maxJetNum);
        MCHHelper.vehicleLimit.put("TANK", maxTankNum);
        MCHHelper.vehicleLimit.put("AA", maxAANum);
        MCHHelper.vehicleLimit.put("HELI", maxHeliNum);
        MCHHelper.vehicleLimit.put("TRANS", maxTransHeliNum);
        MCHHelper.vehicleLimit.put("FAC", maxFacNum);
    }

    protected void applyVehicleCooldown() {
        MCHHelper.vehicleCooldown.clear();
        MCHHelper.vehicleCooldown.put("LIGHT", lightVehicleCooldownTime);
        MCHHelper.vehicleCooldown.put("ATKJET", atkJetCooldownTime);
        MCHHelper.vehicleCooldown.put("JET", jetCooldownTime);
        MCHHelper.vehicleCooldown.put("TANK", tankCooldownTime);
        MCHHelper.vehicleCooldown.put("AA", aaCooldownTime);
        MCHHelper.vehicleCooldown.put("HELI", heliCooldownTime);
        MCHHelper.vehicleCooldown.put("TRANS", transHeliCooldownTime);
        MCHHelper.vehicleCooldown.put("FAC", facCooldownTime);
    }

    public void initVehicleCount() {
        vehicleInfo.put("1_LIGHT", 0);
        vehicleInfo.put("1_TANK", 0);
        vehicleInfo.put("1_AA", 0);
        vehicleInfo.put("1_HELI", 0);
        vehicleInfo.put("1_TRANS", 0);
        vehicleInfo.put("1_JET", 0);
        vehicleInfo.put("1_ATKJET", 0);
        vehicleInfo.put("1_FAC", 0);

        vehicleInfo.put("2_LIGHT", 0);
        vehicleInfo.put("2_TANK", 0);
        vehicleInfo.put("2_AA", 0);
        vehicleInfo.put("2_HELI", 0);
        vehicleInfo.put("2_TRANS", 0);
        vehicleInfo.put("2_JET", 0);
        vehicleInfo.put("2_ATKJET", 0);
        vehicleInfo.put("2_FAC", 0);
    }

    public GameBase setMaxTankNum(int maxTankNum) {
        this.maxTankNum = maxTankNum;
        return this;
    }

    public GameBase setMaxAANum(int maxAANum) {
        this.maxAANum = maxAANum;
        return this;
    }

    public GameBase setMaxHeliNum(int maxHeliNum) {
        this.maxHeliNum = maxHeliNum;
        return this;
    }

    public GameBase setMaxTransHeliNum(int maxTransHeliNum) {
        this.maxTransHeliNum = maxTransHeliNum;
        return this;
    }


    public GameBase setMaxJetNum(int maxJetNum) {
        this.maxJetNum = maxJetNum;
        return this;
    }

    public GameBase setMaxAtkJetNum(int maxAtkJetNum) {
        this.maxAtkJetNum = maxAtkJetNum;
        return this;
    }

    public GameBase setMaxFacNum(int maxFacNum) {
        this.maxFacNum = maxFacNum;
        return this;
    }

    public GameBase setMaxLightVehicleNum(int maxLightVehicleNum) {
        this.maxLightVehicleNum = maxLightVehicleNum;
        return this;
    }

    public class GameThread extends BukkitRunnable {
        @Override
        public void run() {

            if (frame < maxTime) {
                frame++;
            } else {
                frame = 0;
            }

            currentTime--;
            showGameInfo();

            tick(1);

            if (commanderSystem != null) {
                commandSystemTick();
            }

            if (aiSystem != null) {
                aiSystem.tick(1);
            }

            if (executeEnd) {
                showExecuteHUD(firstFactionList);
                showExecuteHUD(secondFactionList);
                onEnd("管理员强制结束该局游戏");
                cancel();
            }

            if (currentTime <= 0) {
                EnumGameType type = gameType;
                if (firstFactionTicket < secondFactionTicket) {
                    showWinHUD(secondFactionList);
                    showLoseHUD(firstFactionList);
                    Bukkit.getPluginManager().callEvent(new GameWinEvent(secondFactionList, gameType));
                    Bukkit.getPluginManager().callEvent(new GameLoseEvent(firstFactionList, gameType));
                    onEnd("时间已到," + secondFactionName + "阵营胜利(" + secondFactionName + " " + secondFactionTicket + "-" + firstFactionTicket + " " + firstFactionName + ")");
                    cancel();
                }
                if (firstFactionTicket > secondFactionTicket) {
                    showWinHUD(firstFactionList);
                    showLoseHUD(secondFactionList);
                    Bukkit.getPluginManager().callEvent(new GameWinEvent(firstFactionList, gameType));
                    Bukkit.getPluginManager().callEvent(new GameLoseEvent(secondFactionList, gameType));
                    onEnd("时间已到," + firstFactionName + "阵营胜利(" + firstFactionName + " " + firstFactionTicket + "-" + secondFactionTicket + " " + secondFactionName + ")");
                    cancel();
                }
                if (firstFactionTicket == secondFactionTicket) {
                    showSameHUD(firstFactionList);
                    showSameHUD(secondFactionList);
                    Bukkit.getPluginManager().callEvent(new GameSameEvent(firstFactionList, gameType));
                    Bukkit.getPluginManager().callEvent(new GameSameEvent(secondFactionList, gameType));
                    onEnd("时间已到,平局(" + secondFactionName + " " + secondFactionTicket + "-" + firstFactionTicket + " " + firstFactionName + ")");
                    cancel();
                }
            } else {
                if (firstFactionTicket <= 0) {
                    firstFactionTicket = 0;
                    showWinHUD(secondFactionList);
                    showLoseHUD(firstFactionList);
                    Bukkit.getPluginManager().callEvent(new GameWinEvent(secondFactionList, gameType));
                    Bukkit.getPluginManager().callEvent(new GameLoseEvent(firstFactionList, gameType));
                    onEnd(secondFactionName + "阵营胜利(" + secondFactionName + " " + secondFactionTicket + "-" + firstFactionTicket + " " + firstFactionName + ")");
                    cancel();
                }
                if (secondFactionTicket <= 0) {
                    secondFactionTicket = 0;
                    showWinHUD(firstFactionList);
                    showLoseHUD(secondFactionList);
                    Bukkit.getPluginManager().callEvent(new GameWinEvent(firstFactionList, gameType));
                    Bukkit.getPluginManager().callEvent(new GameLoseEvent(secondFactionList, gameType));
                    onEnd(firstFactionName + "阵营胜利(" + firstFactionName + " " + firstFactionTicket + "-" + secondFactionTicket + " " + secondFactionName + ")");
                    cancel();
                }
            }
        }
    }
}
